package com.jrx.anytxn.param.service.aviator.impl;


import com.googlecode.aviator.AviatorEvaluator;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnRuntimeException;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.param.constant.RuleCodeConstant;
import com.jrx.anytxn.param.dto.aviator.RuleMatchReq;
import com.jrx.anytxn.param.dto.aviator.RuleRes;
import com.jrx.anytxn.param.service.aviator.IAviatorService;
import com.jrx.anytxn.param.service.aviator.IRuleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @Author: haopu.zheng
 * @Description: 执行规则
 * @Date: 2019/8/2
 **/
@Service
public class AviatorServiceImpl implements IAviatorService {

    private static final Logger logger = LoggerFactory.getLogger(AviatorServiceImpl.class);
    @Autowired
    private IRuleService ruleServiceImpl;


    @Override
    public String executeRule(RuleMatchReq ruleMatchDTO) {

        String result = "";
        Map ruleParam = ruleMatchDTO.getRuleParam();
        RuleRes req = new RuleRes();
        req.setId(ruleMatchDTO.getId());
        req.setOrganizationNumber(ruleMatchDTO.getOrganizationNumber());
        req.setProductNumber(ruleMatchDTO.getProductNumber());
        req.setRuleType(ruleMatchDTO.getRuleType());
        //有效规则
        req.setRuleStatus("1");
        req.setTenantId(ruleMatchDTO.getTenantId());
        //匹配的所有规则
        List<RuleRes> rulelist = ruleServiceImpl.getByIdOrRuleTypeRule(req);

        if (null == rulelist || rulelist.isEmpty() || null == ruleParam) {
            logger.info("未找到匹配的规则  find not match");
            throw new TxnRuntimeException(RuleCodeConstant.NOT_FIND_RULE_CODE, RuleCodeConstant.NOT_FIND_RULE_MSG);
        }
        Boolean matchFlag = false;

        for (RuleRes res : rulelist) {
            String expression = res.getExpression();
            String format = String.format("rule match expression:%s,ruleParam:%s", expression, ruleParam.toString());
            logger.info(format);
            matchFlag = (Boolean) AviatorEvaluator.execute(expression, ruleParam, true);
            if (matchFlag) {
                result = res.getRuleResult();
                logger.info("rule match result: {}", result);
                break;
            }
        }
        if (!matchFlag) {
            throw new TxnRuntimeException(RuleCodeConstant.NOT_MATCH_RULE_CODE, RuleCodeConstant.NOT_MATCH_RULE_MSG);
        }

        return result;
    }

    @Override
    public Map<String, Object> executeRuleResultMap(RuleMatchReq ruleMatchDTO) throws TxnBizException {
        String resultResMap = executeRule(ruleMatchDTO);
        if (StringUtils.isBlank(resultResMap)) {
            logger.error(RuleCodeConstant.RULE_RESULT_EMPTY);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), RuleCodeConstant.RULE_RESULT_EMPTY);
        }
        try {
            return JsonUtils.json2mapDeeply(resultResMap);
        } catch (Exception e) {
            logger.debug(RuleCodeConstant.RULE_RESULT_CONVERT_MAP_ERROR);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), RuleCodeConstant.RULE_RESULT_CONVERT_MAP_ERROR);
        }
    }

    @Override
    public List<Map<String, Object>> executeRuleList(RuleMatchReq ruleMatchDTO) throws Exception{
        List<Map<String, Object>> allRuleResultList = new ArrayList<>();

        Map ruleParam = ruleMatchDTO.getRuleParam();
        RuleRes req = new RuleRes();
        req.setId(ruleMatchDTO.getId());
        req.setOrganizationNumber(ruleMatchDTO.getOrganizationNumber());
        req.setProductNumber(ruleMatchDTO.getProductNumber());
        req.setRuleType(ruleMatchDTO.getRuleType());
        //有效规则
        req.setRuleStatus("1");
        req.setTenantId(ruleMatchDTO.getTenantId());
        //匹配的所有规则
        List<RuleRes> rulelist = ruleServiceImpl.getByIdOrRuleTypeRule(req);

        if (null == rulelist || rulelist.isEmpty() || null == ruleParam) {
            logger.info("未找到匹配的规则  find not match");
            throw new TxnRuntimeException(RuleCodeConstant.NOT_FIND_RULE_CODE, RuleCodeConstant.NOT_FIND_RULE_MSG);
        }

        for (RuleRes res : rulelist) {
            String expression = res.getExpression();
            String format = String.format("rule match expression:%s,ruleParam:%s", expression, ruleParam.toString());
            logger.info(format);
            Boolean matchFlag = (Boolean) AviatorEvaluator.execute(expression, ruleParam, true);
            if (matchFlag) {
                String result = res.getRuleResult();
                logger.info("rule match result: {}", result);
                allRuleResultList.add(JsonUtils.json2mapDeeply(result));
            }
        }
        return allRuleResultList;
    }


}

